package mq

import (
	"encoding/json"
	"errors"
	"time"
)

var (
	typeLogin = "login" //登录消息
	typeMsg   = "msg"   //普通消息
)

type Msg struct {
	Type     string `json:"type"`
	Topic    string
	ClientTo string
	ClientOf string
	Date     int64
	Data     []byte
	Err      string
}

func (this *Msg) Error() string {
	return this.Err
}

func (this *Msg) bytes() []byte {
	bs, _ := json.Marshal(this)
	return bs
}

func (this *Msg) json() string {
	return string(this.bytes())
}

func (this *Msg) toLogin() *msgLogin {
	msg := new(msgLogin)
	json.Unmarshal(this.Data, msg)
	return msg
}

func (this *Msg) toLoginRes() *msgRes {
	msg := new(msgRes)
	json.Unmarshal(this.Data, msg)
	return msg
}

func newMsg(topic, clientTo, clientOf string, data []byte) *Msg {
	return &Msg{
		Type:     typeMsg,
		Topic:    topic,
		ClientTo: clientTo,
		ClientOf: clientOf,
		Date:     time.Now().UnixNano(),
		Data:     data,
	}
}

type msgLogin struct {
	AppKey string `json:"appKey"`
	Sign   string `json:"sign"`
	Time   int64  `json:"time"`
}

func (this *msgLogin) check(appSecret string) error {
	sign := getSign(appSecret, this.Time)
	if this.Sign != sign {
		return errors.New("登录失败")
	}
	return nil
}

func (this *msgLogin) bytes() []byte {
	bs, _ := json.Marshal(this)
	return bs
}

func newMsgLogin(appKey, appSecret, clientId string, t int64) *Msg {
	msg := &msgLogin{
		AppKey: appKey,
		Sign:   getSign(appSecret, t),
		Time:   t,
	}
	return &Msg{
		Type:     typeLogin,
		ClientOf: clientId,
		Date:     time.Now().UnixNano(),
		Data:     msg.bytes(),
	}
}

type msgRes struct {
	Code int
	Msg  string
}

func newMsgRes(code int, msg string) *msgRes {
	return &msgRes{
		Code: code,
		Msg:  msg,
	}
}

func (this *msgRes) bytes() []byte {
	bs, _ := json.Marshal(this)
	return bs
}

func (this *msgRes) ok() bool {
	return this.Code == 200
}

func (this *msgRes) err() error {
	if this.ok() {
		return nil
	}
	return this
}

func (this *msgRes) Error() string {
	return this.Msg
}
